<?php
/**
 * Created by PhpStorm.
 * User: yui
 * Date: 2017/4/24
 * Time: 1:57
 */

namespace common\services;

use Yii;
use common\models\Assets;
use yii\web\UploadedFile;

class AssetsSve extends BaseSve
{
    //用户
    private $_Uper;

    public function __construct($TokenObj)
    {
        parent::__construct();
        $this->_Uper = $TokenObj;
    }


    /**
     * 上传图片
     * @return array
     */
    public function uploadImage()
    {
        try {
            //获取存储路径
            $path = Yii::$app->request->get('path', '');
            //是否64位编码
            $is64 = intval(Yii::$app->request->get('is64', 0));
            //检查登录
            $this->_checkLogin();
            //检查路径
            $this->_checkPath($path);
            $Assets = new Assets();
            //选择场景
            $Assets->scenario = strtolower($path);
            //获取文件，验证文件
            if ($is64) {
                $Assets->image = $this->_getBase64Image();
            } else {
                $Assets->image = UploadedFile::getInstance($Assets, 'image');
            }
            //检查错误
            self::checkErr($Assets);
            //组装全路径
            $fullPath = $path . DS . date('YmdH') . DS;
            //创建路径
            $this->_createFile($fullPath);
            //创建文件名
            $fileName = $fullPath . md5(uniqid() . microtime(true) . mt_rand(0, 999999)) . '.' . $Assets->image->extension;
            //保存文件
            if ($is64) {
                $rs = $this->_base64SaveFile($Assets->image->tempName, $fileName);
            } else {
                $rs = $Assets->image->saveAs($fileName);
            }
            if ($rs === false) {
                throw new \Exception('上传失败', -1);
            }
            //图片压缩
            $this->thumbImage($path, $fileName);
            //记录上传
            $this->_logUpload($fileName, 'image');
            return self::result('上传成功', 0, [
                'path' => $fileName,
                'src' => HTTP_DOMAIN_ASSETS . DS . $fileName
            ]);
        } catch (\Exception $e) {
            if (array_key_exists($e->getCode(), OC_ERR_CODE)) {
                return self::result($e->getMessage(), $e->getCode());
            } else {
                return self::result('系统繁忙', -50);
            }
        }
    }

    public function uploadVideo()
    {
        try {
            //获取存储路径
            $path = Yii::$app->request->get('path', '');
            //检查登录
            $this->_checkLogin();
            //检查路径
            $this->_checkPath($path);
            $Assets = new Assets();
            //选择场景
            $Assets->scenario = strtolower($path);
            //验证文件
            $Assets->video = UploadedFile::getInstance($Assets, 'video');
            //检查错误
            self::checkErr($Assets);
            //组装全路径
            $fullPath = $path . DS . date('YmdH') . DS;
            //创建路径
            $this->_createFile($fullPath);
            //创建文件名
            $fileName = $fullPath . md5(uniqid() . microtime(true) . mt_rand(0, 999999)) . '.' . $Assets->video->extension;
            //保存文件
            $rs = $Assets->video->saveAs($fileName);
            if ($rs === false) {
                throw new \Exception('上传失败', -1);
            }
            //记录上传
            $this->_logUpload($fileName, 'video');
            return self::result('上传成功', 0, [
                'path' => $fileName,
                'src' => HTTP_DOMAIN_ASSETS . DS . $fileName
            ]);
        } catch (\Exception $e) {
            if (array_key_exists($e->getCode(), OC_ERR_CODE)) {
                return self::result($e->getMessage(), $e->getCode());
            } else {
                return self::result('系统繁忙', -50);
            }
        }
    }

    /**
     * 压缩图片
     * @param $path
     * @param $filePath
     */
    public function thumbImage($path, $filePath)
    {

        $imagine = new \Imagine\Imagick\Imagine();
        switch ($path) {
            case 'user_avatar':
                $size = new \Imagine\Image\Box(Yii::$app->params['user_avatar_width'], Yii::$app->params['user_avatar_height']);
                $mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
                $imagine->open($filePath)->thumbnail($size, $mode)
                    ->save($filePath);
                break;
            case 'logo':
                $size = new \Imagine\Image\Box(Yii::$app->params['logo_width'], Yii::$app->params['logo_height']);
                $mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
                $imagine->open($filePath)->thumbnail($size, $mode)
                    ->save($filePath);
                break;
            case 'ico':
                $size = new \Imagine\Image\Box(Yii::$app->params['ico_width'], Yii::$app->params['ico_height']);
                $mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
                $imagine->open($filePath)->thumbnail($size, $mode)
                    ->save($filePath);
                break;
            case 'works':
                $size = new \Imagine\Image\Box(OC['works_width'], OC['works_height']);
                $mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
                $imagine->open($filePath)->thumbnail($size, $mode)
                    ->save($filePath);
                break;
        }
    }

    /**
     * base64上传的图片保存
     * @param $tempFile //临时文件路径
     * @param $newFile //新文件路径
     * @param bool $deleteTempFile //是否删除
     * @return bool
     */
    private function _base64SaveFile($tempFile, $newFile, $deleteTempFile = true)
    {
        if ($deleteTempFile) {
            copy($tempFile, $newFile);
            return unlink($tempFile);
        } else {
            return copy($tempFile, $newFile);
        }
    }

    /**
     * 获取base64图片
     * @return UploadedFile
     * @throws \Exception
     */
    private function _getBase64Image()
    {
        //转成文件放到临时目录
        $post = Yii::$app->request->post();
        //获取字符串
        $imageBase64Str = $post['Assets']['image']??'';
        if (empty($imageBase64Str)) {
            throw new \Exception('base64数据不能为空', -1);
        }
        //去除前23个字符
        $imageBase64Str = substr($imageBase64Str, 23);
        //解码
        $imageStr = base64_decode($imageBase64Str);
        //文件存储位置
        $filePath = 'temp/' . md5(uniqid() . microtime(true) . mt_rand(0, 999999)) . '.jpg';
        //转存临时文件
        $int = file_put_contents($filePath, $imageStr);
        if (!$int) {
            throw new \Exception('文件写入失败', -1);
        }

        //路径信息
        $pathPartsArr = pathinfo($filePath);
        //图片信息
        $sizeArr = getimagesize($filePath);
        //数据写入对象
        $UploadedFile = new UploadedFile();
        $UploadedFile->name = $pathPartsArr['basename'];
        $UploadedFile->tempName = getcwd() . DS . $filePath;
        $UploadedFile->type = $sizeArr['mime'];
        $UploadedFile->size = filesize($UploadedFile->tempName);
        $UploadedFile->error = 0;

        return $UploadedFile;
    }

    /**
     * 检查、创建目录
     * @param $fullPath
     * @throws \Exception
     */
    private function _createFile($fullPath)
    {
        //检查目录是否存在
        if (!is_dir($fullPath)) {
            //创建目录
            if (!mkdir($fullPath, 0775, true)) {
                throw new \Exception('创建保存目录失败', -1);
            }
        }
        //检查目录权限
        if (!is_writeable($fullPath)) {
            throw new \Exception('上传目录' . $fullPath . '不可写', -1);
        }
    }

    /**
     * 检查路径并选择场景
     * @param $path
     * @param $Assets
     * @throws \Exception
     */
    private function _checkPath($path)
    {
        switch ($path) {
            case 'other':
            case 'banner':
            case 'user_avatar':
            case 'logo':
            case 'ico':
                //仅限商户、后台
                if (isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], [HTTP_DOMAIN_ADMIN])) {
                    //允许跨域
                    Yii::$app->response->headers->set('Access-Control-Allow-Origin', $_SERVER['HTTP_ORIGIN']);
                } else {
                    throw new \Exception('无效域名', -1);
                }
                break;
            case 'goods_desc':
            case 'goods':
                //仅限商户、后台
                if (isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], [HTTP_DOMAIN_ADMIN])) {
                    //允许跨域
                    Yii::$app->response->headers->set('Access-Control-Allow-Origin', $_SERVER['HTTP_ORIGIN']);
                } else {
                    throw new \Exception('无效域名', -1);
                }
                break;
            case 'member_avatar':
            case 'works':
            case 'qrcode':
                //仅限用户
                //检查上传限制
                break;
            case 'article'://文章
                //仅限后台
                if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] == HTTP_DOMAIN_ADMIN) {
                    //允许跨域
                    Yii::$app->response->headers->set('Access-Control-Allow-Origin', HTTP_DOMAIN_ADMIN);
                } else {
                    throw new \Exception('无效域名', -1);
                }
                break;
            case 'video':
                //仅限后台
                if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] == HTTP_DOMAIN_ADMIN) {
                    //允许跨域
                    Yii::$app->response->headers->set('Access-Control-Allow-Origin', HTTP_DOMAIN_ADMIN);
                } else {
                    throw new \Exception('无效域名', -1);
                }
                break;
            default:
                throw new \Exception('非法路径', -1);
                break;
        }
    }

    /**
     * 记录上传
     * @param $path
     * @param $type
     * @param int $lifetime
     * @throws \Exception
     */
    private function _logUpload($path, $type, $lifetime = 0)
    {
        //获取主键名
        $primaryKey = $this->_Uper->primaryKey()[0];
        //获取用户类型
        if ($primaryKey != 'id') {
            $uperType = substr($primaryKey, 0, -3);
        } else {
            $uperType = 'user';
        }
        //记录上传资源
        $AssetsLogSve = new AssetsLogSve();
        $rs = $AssetsLogSve->add([
            'uper_id' => $this->_Uper[$primaryKey],
            'uper_type' => $uperType,
            'path' => $path,
            'type' => $type,
            'lifetime' => $lifetime,
            'create_time' => $_SERVER['REQUEST_TIME']
        ]);
        if ($rs['code'] !== 0) {
            throw new \Exception($rs['msg'], -1);
        }
    }

    /**
     * 检查登录
     * @throws \Exception
     */
    private function _checkLogin()
    {
        if (empty($this->_Uper)) {
            throw new \Exception('请登录后操作', -1);
        }
    }
}